package opc.read.sycread;

import lombok.SneakyThrows;
import opc.read.utils.MyCopyOnWriteMap;
import opc.read.utils.ReadHostProt;
import org.openscada.opc.lib.common.ConnectionInformation;
import org.openscada.opc.lib.da.*;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @Description:  opcserver模拟仙鹤的信号的异步测试读取，测试失败
 * @author: liyuan
 * @data 2021-01-06 10:21
 */
public class ByDemoAsyRead {
    public static void main(String[] args) throws IOException {
        ByDemoAsyRead.DemoAPI();
    }
    public static void DemoAPI() throws IOException {

        Map<String, String> dataSources = ReadHostProt.loadFile();

        final ConnectionInformation ci = new ConnectionInformation();
        final SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        ci.setHost(dataSources.get("host"));
        ci.setDomain(dataSources.get("domain"));
        ci.setUser(dataSources.get("user"));
        ci.setPassword(dataSources.get("password"));
        ci.setClsid(dataSources.get("clsid"));
        final Map<String, Map<String, Item>> result = new LinkedHashMap<String, Map<String, Item>>();
        final Map<String, Object> resultNew = new MyCopyOnWriteMap<String, Object>(new LinkedHashMap<String, Object>());
//        final Server server = new Server(ci, Executors.newSingleThreadScheduledExecutor());
        final Server server = new Server(ci, Executors.newSingleThreadScheduledExecutor());
//        final AutoReconnectController autoReconnectController = new AutoReconnectController(server);
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
        try {

            // connect to server
//            autoReconnectController.connect();
            server.connect();
            int size = Integer.parseInt(dataSources.get("len"));
//            final AccessBase access = new SyncAccess(server, 1000);
            final AccessBase access = new Async20Access(server, 1000, false);
            for (int i = 0; i < size; i++) {
                //设置group对象
                String groupName = dataSources.get("deviceName" + i);
                /***
                 *  构造信号集合“：resultItemMap   {	"CST28214": "", 	"SP28214_RD": ""}
                 */
                String[] split = dataSources.get("deviceName" + i + ".deviceItem").split(",");
                Group group = null;
                group = server.addGroup(groupName);
                group.setActive(true);
                Map<String, Item> itemMap = group.addItems(split);
                result.put(groupName, itemMap);
                Map<String, Object> itemNewMap = new LinkedHashMap<String, Object>();
                for (String key : itemMap.keySet()) {
                    itemNewMap.put(key, null);
                }
                resultNew.put(groupName, itemNewMap);
            }

            //首先遍历读一遍
            resultNew.put("date", System.currentTimeMillis());
            for (final String groupName : result.keySet()) {
                Map<String, Item> itemMap = result.get(groupName);
                //组内部的读取信号
                for (Map.Entry<String, Item> map : itemMap.entrySet()) {
                    if (map.getValue() instanceof Item) {
                        Item item = map.getValue();
                        Object object = item.read(false).getValue().getObject();
                        Short quality = item.read(false).getQuality();
//                        if (quality < 192) object = null; // 当信号质量值小于192的时候，表示该信号有问题，该信号值赋值为null
                        ((Map<String, Object>) resultNew.get(groupName)).put(item.getId(), object);  // 去掉xianhe.设备 1., 只留下需要的信号名

                    }
                }
            }


            //新开线程池执行写任务
            scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
                @Override
                public void run() {
//                    String s = JSON.toJSONString(resultNew);
//                    System.out.println("--json---");
//                    System.out.println(s);
//                    WriterFile.writeTxtFile(s, new File("d:/ProDataAccess/xianhe/data2/file2/" + formatter.format(new Date()) + ".txt"), "utf-8");

                }
                //单位毫秒
            }, 1000, 1000, TimeUnit.MILLISECONDS);
            //主线程一直在读取数据

/***
 异步接口的api应该不对；；
 * */
            resultNew.put("date", System.currentTimeMillis());

            for (final String groupName : result.keySet()) {
                Map<String, Item> itemMap = result.get(groupName);

                //组内部的读取信号
                for (Map.Entry<String, Item> map : itemMap.entrySet()) {
                    access.addItem(map.getKey(), new DataCallback() {
                        @SneakyThrows
                        @Override
                        public void changed(Item item, ItemState state) {

                            System.out.println("success");
                            System.out.println(item.getId()+state.getValue().getObject());
                            //取出来再次放入新的值
                            ((Map<String, Object>) resultNew.get(groupName)).put(item.getId(), state.getValue().getObject());
                        }
                    });

                }
            }
            /** 异步开始读取 **/
            access.bind();
            Thread.sleep(1000*10);
            access.unbind();
            System.out.println("执行吗");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
